package com.android.launcher3;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;

import org.metalev.multitouch.controller.MultiTouchController;
import org.metalev.multitouch.controller.MultiTouchController.MultiTouchObjectCanvas;
import org.metalev.multitouch.controller.MultiTouchController.PointInfo;
import org.metalev.multitouch.controller.MultiTouchController.PositionAndScale;

import android.app.WallpaperManager;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.WindowManager;
import android.widget.Scroller;
import android.widget.TextView;

/**
 * The workspace is a wide area with a wallpaper and a finite number of screens.
 * Each screen contains a number of icons, folders or widgets the user can
 * interact with. A workspace is meant to be used with a fixed width only.
 */
public class Workspace extends ViewGroup implements DropTarget, DragSource,
		DragScroller, MultiTouchObjectCanvas<Object> {
	final Rect mClipBounds = new Rect();
	final Rect mDrawerBounds = new Rect();

	int mDrawerContentHeight;
	int mDrawerContentWidth;

	private final WallpaperManager mWallpaperManager;

	/** CellInfo for the cell that is currently being dragged */
	private CellLayout.CellInfo mDragInfo;

	/**
	 * Cache of vacant cells, used during drag events and invalidated as needed.
	 */
	private CellLayout.CellInfo mVacantCache = null;

	private DragController mDragger;
	private Drawable mPageIndicatorLarge;
	private Drawable mPageIndicatorMiddle;
	private Drawable mPageIndicatorSmall;

	private IconCache mIconCache;
	private Launcher mLauncher;
	private OnLongClickListener mLongClickListener;
	private PageIndicator mPageIndicator;
	private Rect mTmpRect;
	private Runnable mAutoScrollRunnable;
	private Scroller mScroller;
	// private VelocityTracker mVelocityTracker;

	/** Target drop area calculated during last acceptDrop call. */
	private int[] mTargetCell = null;
	private int[] mTempCell = new int[2];
	private int[] mTempEstimate = new int[2];
	private boolean mAllowLongPress;
	private boolean mEnablePageIndicatorShowHide;
	private boolean mFirstLayout = true;
	private boolean mIsAutoScrolling;
	private boolean mLocked;
	private boolean mOpenFlag;
	private boolean mUseLargeDrawablesOnlyForPageIndicator;
	private float mLastMotionX;
	private float mLastDownX;
	private float mLastMotionY;
	private final int CHILD_WIDTH;
	private int mChildTopOffset;
	private int mCurrentScreen;
	private int mDefaultScreen;
	private int mEndScreen;
	// private int mMaximumVelocity;
	private int mNextScreen = INVALID_SCREEN;
	private int mPageIndicatorGap;
	private int mPageIndicatorLeft;
	private int mPageIndicatorTop;
	private int mScrollDirection;
	private int mStartScreen;
	private int mTextSize;
	private int mTouchSlop;
	private int mTouchState = TOUCH_STATE_REST;
	private static final int INVALID_SCREEN = -1;

	/**
	 * The velocity at which a fling gesture will cause us to snap to the next
	 * screen
	 */
	private static final int SNAP_VELOCITY = 10;
	private static final int TOUCH_STATE_REST = 0;
	private static final int SCROLL_RESTART_DURATION = 1000;
	private static final int SNAPTOSCREEN_DURATION = 400;
	private static final int SNAPTOSCREEN_DURATION_HORIZONTAL = 600;
	private static final int TOUCH_STATE_SCROLLING = 1;
	private static final String TAG = "Workspace";
	private static int mAninmationType = 0;
	private static int originalAninmationType;

	// ADW: sense zoom constants
	private static final int SENSE_OPENING = 1;
	private static final int SENSE_CLOSING = 2;
	private static final int SENSE_OPEN = 3;
	private static final int SENSE_CLOSED = 4;
	// ADW: sense zoom variables
	private boolean mSensemode = false;
	private boolean isAnimating = false;
	private long startTime;
	private int mStatus = SENSE_CLOSED;
	private final int mAnimationDuration = 400;
	private final int[][] distro = { { 1 }, { 2 }, { 1, 2 }, { 2, 2 },
			{ 2, 1, 2 }, { 2, 2, 2 }, { 2, 3, 2 }, { 3, 2, 3 }, { 3, 3, 3 } };
	private float previewScale = 1;
	// Wysie: Multitouch controller
	private MultiTouchController<Object> multiTouchController;
	private static final double ZOOM_SENSITIVITY = 1.6;
	private static final double ZOOM_LOG_BASE_INV = 1.0 / Math
			.log(2.0 / ZOOM_SENSITIVITY);

	final Camera mCamera = new Camera();

	/**
	 * Used to inflate the Workspace from XML.
	 * 
	 * @param context
	 *            The application's context.
	 * @param attrs
	 *            The attribtues set containing the Workspace's customization
	 *            values.
	 */
	public Workspace(final Context context, final AttributeSet attrs) {
		this(context, attrs, 0);
	}

	/**
	 * Used to inflate the Workspace from XML.
	 * 
	 * @param context
	 *            The application's context.
	 * @param attrs
	 *            The attribtues set containing the Workspace's customization
	 *            values.
	 * @param defStyle
	 *            Unused.
	 */
	public Workspace(final Context context, final AttributeSet attrs,
			final int defStyle) {
		super(context, attrs, defStyle);

		this.mAutoScrollRunnable = new Runnable() {
			public void run() {
			}
		};

		mWallpaperManager = WallpaperManager.getInstance(context);

		// TypedArray a = context.obtainStyledAttributes(attrs,
		// R.styleable.Workspace,
		// defStyle, 0);
		// mDefaultScreen = a.getInt(R.styleable.Workspace_defaultScreen, 4);

		// a.recycle();

		mDefaultScreen = 4;

		this.mUseLargeDrawablesOnlyForPageIndicator = LauncherConfig
				.pageIndicator_getUseLargeDrawablesOnly(context);
		// Log.e(TAG,"mUseLargeDrawablesOnlyForPageIndicator "+mUseLargeDrawablesOnlyForPageIndicator);
		initWorkspace();
		CHILD_WIDTH = ((WindowManager) context
				.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()
				.getWidth();
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean acceptDrop(final DragSource source, final int x,
			final int y, final int xOffset, final int yOffset,
			final Object dragInfo) {
		LogUtils.d(TAG, "acceptDrop");

		final CellLayout layout = getCurrentDropLayout();
		final CellLayout.CellInfo cellInfo = mDragInfo;
		final int spanX = cellInfo == null ? 1 : cellInfo.spanX;
		final int spanY = cellInfo == null ? 1 : cellInfo.spanY;

		if (mVacantCache == null) {
			final View ignoreView = cellInfo == null ? null : cellInfo.cell;
			mVacantCache = layout.findAllVacantCells(null, ignoreView);
		}

		return mVacantCache.findCellForSpan(mTempEstimate, spanX, spanY, false);
	}

	@Override
	public void addFocusables(final ArrayList<View> views, final int direction,
			final int focusableMode) {
		final Folder openFolder = getOpenFolder();

		if (openFolder == null) {
			getChildAt(mCurrentScreen).addFocusables(views, direction);

			if (direction == View.FOCUS_LEFT) {
				if (mCurrentScreen > 0) {
					getChildAt(mCurrentScreen - 1).addFocusables(views,
							direction);
				}
			} else if (direction == View.FOCUS_RIGHT) {
				if (mCurrentScreen < getChildCount() - 1) {
					getChildAt(mCurrentScreen + 1).addFocusables(views,
							direction);
				}
			}
		} else {
			openFolder.addFocusables(views, direction);
		}
	}

	@Override
	public void addView(final View child) {
		if (!(child instanceof CellLayout)) {
			throw new IllegalArgumentException(
					"A Workspace can only have CellLayout children.");
		}

		super.addView(child);
		recomputeDefaultScreen();
	}

	@Override
	public void addView(final View child, final int index) {
		if (!(child instanceof CellLayout)) {
			throw new IllegalArgumentException(
					"A Workspace can only have CellLayout children.");
		}
		super.addView(child, index);
		recomputeDefaultScreen();
	}

	@Override
	public void addView(final View child, final int width, final int height) {
		if (!(child instanceof CellLayout)) {
			throw new IllegalArgumentException(
					"A Workspace can only have CellLayout children.");
		}
		super.addView(child, width, height);
		recomputeDefaultScreen();
	}

	@Override
	public void addView(final View child, final int index,
			final LayoutParams params) {
		if (!(child instanceof CellLayout)) {
			throw new IllegalArgumentException(
					"A Workspace can only have CellLayout children.");
		}
		super.addView(child, index, params);
		recomputeDefaultScreen();
	}

	@Override
	public void addView(final View child, final LayoutParams params) {
		if (!(child instanceof CellLayout)) {
			throw new IllegalArgumentException(
					"A Workspace can only have CellLayout children.");
		}
		super.addView(child, params);
		recomputeDefaultScreen();
	}

	/**
	 * 贺辉增加 2011年10月18日10:19:52
	 */
	void recomputeDefaultScreen() {
		this.mDefaultScreen = this.getChildCount() / 2;
	}

	/**
	 * DOCUMENT ME!
	 * 
	 * @return True is long presses are still allowed for the current touch
	 */
	public boolean allowLongPress() {
		return mAllowLongPress;
	}

	@Override
	public void computeScroll() {
		if (mScroller.computeScrollOffset()) {
			mScrollX = mScroller.getCurrX();
			mScrollY = mScroller.getCurrY();
			updateWallpaperOffset();
			postInvalidate();
		} else if (mNextScreen != INVALID_SCREEN) {
			mCurrentScreen = Math.max(0,
					Math.min(mNextScreen, getChildCount() - 1));
			Launcher.setScreen(mCurrentScreen);
			mNextScreen = INVALID_SCREEN;
			clearChildrenCache();
		}
		// myLayout(mScrollX);
	}

	@Override
	public void removeView(View view) {
		super.removeView(view);
		this.recomputeDefaultScreen();
	}

	@Override
	public boolean dispatchUnhandledMove(final View focused, final int direction) {
		if (direction == View.FOCUS_LEFT) {
			if (getCurrentScreen() > 0) {
				snapToScreen(getCurrentScreen() - 1);

				return true;
			}
		} else if (direction == View.FOCUS_RIGHT) {
			if (getCurrentScreen() < getChildCount() - 1) {
				snapToScreen(getCurrentScreen() + 1);

				return true;
			}
		}

		return super.dispatchUnhandledMove(focused, direction);
	}

	public void drawWallpaperImage(final Canvas canvas, final Rect rect) {
		Drawable localDrawable;

		if (this.mLauncher.getMenuManager().isOpened()) {
			localDrawable = this.mLauncher
					.getCurrentImageMenuWallpaperDrawable();
		} else {
			localDrawable = this.mLauncher.getCurrentImageWallpaperDrawable();
		}

		if (localDrawable != null) {
			this.mTmpRect.set(rect);
			this.mTmpRect.left = 0;

			Rect localRect1 = this.mTmpRect;
			int i = localDrawable.getIntrinsicWidth();
			localRect1.right = i;

			Rect localRect2 = this.mTmpRect;
			localDrawable.setBounds(localRect2);

			int j = getWidth();
			int k = getChildCount() - 1;
			int m = j * k;
			int n = this.mScrollX;

			if (n < 0) {
				n = 0;
			}

			if (n > m) {
				n = m;
			}

			int i1 = canvas.save();
			int i2 = localDrawable.getIntrinsicWidth();
			int i3 = rect.width();
			int i4 = i2 - i3;
			float f1 = 0.0F;

			if (getChildCount() > 1) {
				float f2 = -i4;
				float f3 = n;
				float f4 = m;
				float f5 = f3 / f4;
				f1 = f2 * f5;
			}

			canvas.translate(f1, 0.0F);
			localDrawable.draw(canvas);
			canvas.restoreToCount(i1);
		}

		return;
	}

	/**
	 * {@inheritDoc}
	 */
	public Rect estimateDropLocation(final int x, final int y,
			final int xOffset, final int yOffset, final Rect recycle) {
		final CellLayout layout = getCurrentDropLayout();

		final CellLayout.CellInfo cellInfo = mDragInfo;
		final int spanX = cellInfo == null ? 1 : cellInfo.spanX;
		final int spanY = cellInfo == null ? 1 : cellInfo.spanY;
		final View ignoreView = cellInfo == null ? null : cellInfo.cell;

		final Rect location = recycle != null ? recycle : new Rect();

		// Find drop cell and convert into rectangle
		int[] dropCell = estimateDropCell(x - xOffset, y - yOffset, spanX,
				spanY, ignoreView, layout, mTempCell);

		if (dropCell == null) {
			return null;
		}

		layout.cellToPoint(dropCell[0], dropCell[1], mTempEstimate);
		location.left = mTempEstimate[0];
		location.top = mTempEstimate[1];

		layout.cellToPoint(dropCell[0] + spanX, dropCell[1] + spanY,
				mTempEstimate);
		location.right = mTempEstimate[0];
		location.bottom = mTempEstimate[1];

		return location;
	}

	/**
	 * Gets the first search widget on the current screen, if there is one.
	 * Returns <code>null</code> otherwise.
	 */
	public Search findSearchWidgetOnCurrentScreen() {
		CellLayout currentScreen = (CellLayout) getChildAt(mCurrentScreen);

		return findSearchWidget(currentScreen);
	}

	public Folder getFolderForTag(final Object tag) {
		int screenCount = getChildCount();

		for (int screen = 0; screen < screenCount; screen++) {
			CellLayout currentScreen = ((CellLayout) getChildAt(screen));
			int count = currentScreen.getChildCount();

			for (int i = 0; i < count; i++) {
				View child = currentScreen.getChildAt(i);
				CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child
						.getLayoutParams();

				if (lp.cellHSpan == 4 && lp.cellVSpan == 4
						&& child instanceof Folder) {
					Folder f = (Folder) child;

					if (f.getInfo() == tag) {
						return f;
					}
				}
			}
		}

		return null;
	}

	public int getScreenForView(final View v) {
		int result = -1;

		if (v != null) {
			ViewParent vp = v.getParent();
			int count = getChildCount();

			for (int i = 0; i < count; i++) {
				if (vp == getChildAt(i)) {
					return i;
				}
			}
		}

		return result;
	}

	public View getViewForTag(final Object tag) {
		int screenCount = getChildCount();

		for (int screen = 0; screen < screenCount; screen++) {
			CellLayout currentScreen = ((CellLayout) getChildAt(screen));
			int count = currentScreen.getChildCount();

			for (int i = 0; i < count; i++) {
				View child = currentScreen.getChildAt(i);

				if (child.getTag() == tag) {
					return child;
				}
			}
		}

		return null;
	}

	@Override
	public boolean isOpaque() {
		return false;
	}

	/**
	 * Locks the SlidingDrawer so that touch events are ignores.
	 */
	public void lock() {
		mLocked = true;
	}

	public void onDragEnter(final DragSource source, final int x, final int y,
			final int xOffset, final int yOffset, final Object dragInfo) {
		LogUtils.d(TAG, "onDragEnter");
		clearVacantCache();
	}

	public void onDragExit(final DragSource source, final int x, final int y,
			final int xOffset, final int yOffset, final Object dragInfo) {
		LogUtils.d(TAG, "onDragExit");
		clearVacantCache();
	}

	public void onDragOver(final DragSource source, final int x, final int y,
			final int xOffset, final int yOffset, final Object dragInfo) {
		LogUtils.d(TAG, "onDragOver");
	}

	public void onDrop(final DragSource source, final int x, final int y,
			final int xOffset, final int yOffset, final Object dragInfo) {
		LogUtils.d(TAG, "onDrop");

		final CellLayout cellLayout = getCurrentDropLayout();

		if (source != this) {
			onDropExternal(x - xOffset, y - yOffset, dragInfo, cellLayout);
		} else {
			// Move internally
			if (mDragInfo != null) {
				final View cell = mDragInfo.cell;
				int index = mScroller.isFinished() ? mCurrentScreen
						: mNextScreen;

				if (index != mDragInfo.screen) {
					final CellLayout originalCellLayout = (CellLayout) getChildAt(mDragInfo.screen);
					originalCellLayout.removeView(cell);
					cellLayout.addView(cell);
				}

				mTargetCell = estimateDropCell(x - xOffset, y - yOffset,
						mDragInfo.spanX, mDragInfo.spanY, cell, cellLayout,
						mTargetCell);
				cellLayout.onDropChild(cell, mTargetCell);

				final ItemInfo info = (ItemInfo) cell.getTag();
				CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell
						.getLayoutParams();
				LauncherModel.moveItemInDatabase(mLauncher, info,
						LauncherSettings.Favorites.CONTAINER_DESKTOP, index,
						lp.cellX, lp.cellY);
			}
		}
	}

	public void onDropCompleted(final View target, final boolean success,
			final Object dragInfo) {
		// This is a bit expensive but safe
		LogUtils.d(TAG, "onDropCompleted");
		clearVacantCache();

		if (success) {
			if (target != this && mDragInfo != null) {
				final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen);
				cellLayout.removeView(mDragInfo.cell);

				// final Object tag = mDragInfo.cell.getTag();
				// Launcher.getModel().removeDesktopItem((ItemInfo) tag);
			}
		} else {
			if (mDragInfo != null) {
				final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen);
				cellLayout.onDropAborted(mDragInfo.cell);
			}
		}

		mDragInfo = null;
	}

	@Override
	public boolean onInterceptTouchEvent(final MotionEvent ev) {
		if (mLocked) {
			LogUtils.d(TAG, "onInterceptTouchEvent=" + ev.getAction()
					+ ", return true");

			return true;
		}

		// Wysie: If multitouch event is detected
		if (multiTouchController.onTouchEvent(ev)) {
			return false;
		}

		/*
		 * This method JUST determines whether we want to intercept the motion.
		 * If we return true, onTouchEvent will be called and we do the actual
		 * scrolling there.
		 */

		/*
		 * Shortcut the most recurring case: the user is in the dragging state
		 * and he is moving his finger. We want to intercept this motion.
		 */
		final int action = ev.getAction();

		if ((action == MotionEvent.ACTION_MOVE)
				&& (mTouchState != TOUCH_STATE_REST)) {
			LogUtils.d(TAG, "onInterceptTouchEvent=" + ev.getAction()
					+ ", return true");

			return true;
		}

		final float x = ev.getX();
		final float y = ev.getY();

		switch (action) {
		case MotionEvent.ACTION_MOVE:

			/*
			 * mIsBeingDragged == false, otherwise the shortcut would have
			 * caught it. Check whether the user has moved far enough from his
			 * original down touch.
			 */

			/*
			 * Locally do absolute value. mLastMotionX is set to the y value of
			 * the down event.
			 */
			final int xDiff = (int) Math.abs(x - mLastMotionX);
			final int yDiff = (int) Math.abs(y - mLastMotionY);

			final int touchSlop = mTouchSlop;
			boolean xMoved = xDiff > touchSlop;
			boolean yMoved = yDiff > touchSlop;

			if (xMoved || yMoved) {
				if (xMoved) {
					// Scroll if the user moved far enough along the X axis
					mTouchState = TOUCH_STATE_SCROLLING;
					enableChildrenCache();
				}

				// Either way, cancel any pending longpress
				if (mAllowLongPress) {
					mAllowLongPress = false;

					// Try canceling the long press. It could also have been
					// scheduled
					// by a distant descendant, so use the mAllowLongPress flag
					// to block
					// everything
					final View currentScreen = getChildAt(mCurrentScreen);
					currentScreen.cancelLongPress();
				}
			}

			break;

		case MotionEvent.ACTION_DOWN:
			// Remember location of down touch
			mLastMotionX = x;
			mLastMotionY = y;
			mLastDownX = x;
			mAllowLongPress = true;

			/*
			 * If being flinged and user touches the screen, initiate drag;
			 * otherwise don't. mScroller.isFinished should be false when being
			 * flinged.
			 */
			mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST
					: TOUCH_STATE_SCROLLING;

			// 变换滑动的随机效果
			if (originalAninmationType == 1) {
				mAninmationType = (int) (Math.random() * 11) + 1;
			}
			break;

		case MotionEvent.ACTION_CANCEL:
		case MotionEvent.ACTION_UP:

			if (mTouchState != TOUCH_STATE_SCROLLING) {
				final CellLayout currentScreen = (CellLayout) getChildAt(mCurrentScreen);

				if (!currentScreen.lastDownOnOccupiedCell()) {
					// Send a tap to the wallpaper if the last down was on empty
					// space
					mWallpaperManager.sendWallpaperCommand(getWindowToken(),
							"android.wallpaper.tap", (int) ev.getX(),
							(int) ev.getY(), 0, null);
				}
			}

			// Release the drag
			clearChildrenCache();
			mTouchState = TOUCH_STATE_REST;
			mAllowLongPress = false;
			break;
		}

		/*
		 * The only time we want to intercept motion events is if we are in the
		 * drag mode.
		 */
		LogUtils.d(TAG, "onInterceptTouchEvent=" + ev.getAction() + ", return="
				+ (mTouchState != TOUCH_STATE_REST));

		return mTouchState != TOUCH_STATE_REST;
	}

	@Override
	public boolean onTouchEvent(final MotionEvent ev) {
		if (mLocked) {
			LogUtils.d(TAG, "onTouchEvent=" + ev.getAction() + ", return true");

			return true;
		}

		// if (mVelocityTracker == null) {
		// mVelocityTracker = VelocityTracker.obtain();
		// }
		//
		// mVelocityTracker.addMovement(ev);

		final int action = ev.getAction();

		final float x = ev.getX();

		switch (action) {
		case MotionEvent.ACTION_DOWN:

			/*
			 * If being flinged and user touches, stop the fling. isFinished
			 * will be false if being flinged.
			 */
			if (!mScroller.isFinished()) {
				mScroller.abortAnimation();
			}

			// Remember where the motion event started
			mLastMotionX = x;
			mLastDownX = x;
			break;

		case MotionEvent.ACTION_MOVE:

			if (mTouchState == TOUCH_STATE_SCROLLING) {
				// Scroll to follow the motion event
				final int deltaX = (int) (mLastMotionX - x);
				mLastMotionX = x;

				if (deltaX < 0) {
					if (mScrollX > 0) {
						scrollBy(Math.max(-mScrollX, deltaX), 0);
						updateWallpaperOffset();
					}
				} else if (deltaX > 0) {
					final int availableToScroll = getChildAt(
							getChildCount() - 1).getRight()
							- mScrollX - getWidth();

					if (availableToScroll > 0) {
						scrollBy(Math.min(availableToScroll, deltaX), 0);
						updateWallpaperOffset();
					}
				}
			}

			break;

		case MotionEvent.ACTION_UP:

			if (mTouchState == TOUCH_STATE_SCROLLING) {

				// final VelocityTracker velocityTracker = mVelocityTracker;
				// velocityTracker.computeCurrentVelocity(SNAP_VELOCITY,
				// mMaximumVelocity);
				//
				// int velocityX = (int) velocityTracker.getXVelocity();
				//
				// Log.e(TAG,"velocityX "+velocityX);
				//
				// if (velocityX > SNAP_VELOCITY && mCurrentScreen > 0) {
				// // Fling hard enough to move left
				// snapToScreen(mCurrentScreen - 1);
				// } else if (velocityX < -SNAP_VELOCITY
				// && mCurrentScreen < getChildCount() - 1) {
				// // Fling hard enough to move right
				// snapToScreen(mCurrentScreen + 1);
				// } else {
				// snapToDestination();
				// }
				//
				// if (mVelocityTracker != null) {
				// mVelocityTracker.recycle();
				// mVelocityTracker = null;
				// }

				// 贺辉2011年10月25日17:40:52 增加，为了改善滑动灵敏度
				float d = x - mLastDownX;

				if (d > 50) {
					snapToScreen(mCurrentScreen - 1);
				} else {
					if (d < -50) {
						snapToScreen(mCurrentScreen + 1);
					} else {
						snapToDestination();
					}
				}
				// 修改结束

			}

			mTouchState = TOUCH_STATE_REST;

			break;

		case MotionEvent.ACTION_CANCEL:
			mTouchState = TOUCH_STATE_REST;
		}

		LogUtils.d(TAG, "onTouchEvent=" + ev.getAction() + ", return true");

		return true;
	}

	@Override
	public boolean requestChildRectangleOnScreen(final View child,
			final Rect rectangle, final boolean immediate) {
		int screen = indexOfChild(child);

		if (screen != mCurrentScreen || !mScroller.isFinished()) {
			if (!mLauncher.isWorkspaceLocked()) {
				snapToScreen(screen);
			}

			return true;
		}

		return false;
	}

	public void scrollLeft() {
		clearVacantCache();

		if ((this.mNextScreen == INVALID_SCREEN) && (this.mCurrentScreen > 0)
				&& (this.mScroller.isFinished())) {
			snapToScreen(mCurrentScreen - 1);
		}
	}

	public void scrollRight() {
		LogUtils.d(TAG, "scrollRight");

		clearVacantCache();

		if (this.mNextScreen == INVALID_SCREEN) {
			int i = this.mCurrentScreen;
			int j = getChildCount() - 1;

			if ((i < j) && (this.mScroller.isFinished())) {
				snapToScreen(mCurrentScreen + 1);
			}
		}
	}

	/**
	 * Set true to allow long-press events to be triggered, usually checked by
	 * {@link Launcher} to accept or block dpad-initiated long-presses.
	 */
	public void setAllowLongPress(final boolean allowLongPress) {
		mAllowLongPress = allowLongPress;
	}

	public static void setAninmationType(final int aninmationType2) {
		mAninmationType = aninmationType2;
		originalAninmationType = aninmationType2;
	}

	public void setDragger(final DragController dragger) {
		mDragger = dragger;
	}

	/**
	 * Registers the specified listener on each screen contained in this
	 * workspace.
	 * 
	 * @param l
	 *            The listener used to respond to long clicks.
	 */
	@Override
	public void setOnLongClickListener(final OnLongClickListener l) {
		mLongClickListener = l;

		final int count = getChildCount();

		for (int i = 0; i < count; i++) {
			getChildAt(i).setOnLongClickListener(l);
		}
	}

	/**
	 * Unlocks the SlidingDrawer so that touch events are processed.
	 * 
	 * @see #lock()
	 */
	public void unlock() {
		mLocked = false;
	}

	@Override
	protected void dispatchDraw(final Canvas canvas) {
		LogUtils.d(TAG, "dispatchDraw");

		boolean restore = false;

		// // If the all apps drawer is open and the drawing region for the
		// workspace
		// // is contained within the drawer's bounds, we skip the drawing. This
		// requires
		// // the drawer to be fully opaque.
		// if (mLauncher.isDrawerUp()) {
		// final Rect clipBounds = mClipBounds;
		// canvas.getClipBounds(clipBounds);
		// clipBounds.offset(-mScrollX, -mScrollY);
		// if (mDrawerBounds.contains(clipBounds)) {
		// return;
		// }
		// } else if (mLauncher.isDrawerMoving()) {
		// restore = true;
		// canvas.save(Canvas.CLIP_SAVE_FLAG);
		//
		// final View view = mLauncher.getDrawerHandle();
		// final int top = view.getTop() + view.getHeight();
		//
		// canvas.clipRect(mScrollX, top, mScrollX + mDrawerContentWidth,
		// top + mDrawerContentHeight, Region.Op.DIFFERENCE);
		// }
		drawPageIndicator(canvas);

		// ViewGroup.dispatchDraw() supports many features we don't need:
		// clip to padding, layout animation, animation listener, disappearing
		// children, etc. The following implementation attempts to fast-track
		// the drawing dispatch by drawing only what we know needs to be drawn.
		boolean fastDraw = mTouchState != TOUCH_STATE_SCROLLING
				&& mNextScreen == INVALID_SCREEN;

		// If we are not scrolling or flinging, draw only the current screen
		if (fastDraw) {
			drawChild(canvas, getChildAt(mCurrentScreen), getDrawingTime());
		} else {
			final long drawingTime = getDrawingTime();

			// If we are flinging, draw only the current screen and the target
			// screen
			if (mNextScreen >= 0 && mNextScreen < getChildCount()
					&& Math.abs(mCurrentScreen - mNextScreen) == 1) {
				drawChild(canvas, getChildAt(mCurrentScreen), drawingTime);
				drawChild(canvas, getChildAt(mNextScreen), drawingTime);
			} else {
				// If we are scrolling, draw all of our children
				// Log.e(TAG, "dispatchDraw  draw  all  Child");
				final int count = getChildCount();

				for (int i = 0; i < count; i++) {
					drawChild(canvas, getChildAt(i), drawingTime);
				}
			}
		}

		if (restore) {
			canvas.restore();
		}
	}

	@Override
	protected boolean drawChild(final Canvas canvas, final View child,
			final long drawingTime) {
		// Log.e(TAG, "aninmationType "+aninmationType);
		boolean restore = true;

		float distance2 = child.getLeft() - this.mScrollX;

		// if(originalAninmationType == 1) {
		// aninmationType = (int)(Math.random() * 11) + 1;
		// Log.e(TAG, "aninmationType random "+aninmationType);
		// }

		switch (mAninmationType) {
		// 默认,无动画
		case 0:
			restore = false;
			break;

		// 立方体
		case 2: {
			float x = child.getLeft() - distance2 + child.getHeight() / 2;
			float y = child.getHeight() / 2;
			float degree;

			if (distance2 > 0) {
				x = child.getLeft();
			} else {
				x = child.getRight();
			}

			int factor = 50;
			degree = (distance2 / CHILD_WIDTH * 2.0f) * factor;

			if (degree > 90 || degree < -90) {
				return true;
			}

			canvas.save();
			Matrix ctm = new Matrix();
			mCamera.save();
			mCamera.rotateY(degree);
			mCamera.getMatrix(ctm);
			ctm.preTranslate(-x, -y);
			ctm.postTranslate(x, y);
			canvas.concat(ctm);
			mCamera.restore();
			break;
		}

			// 风车
		case 3: {
			int t = -10;
			int x = CHILD_WIDTH / 2;
			Matrix m = canvas.getMatrix();
			float degree = (distance2 / 1000.0f) * 90;
			canvas.save();

			Matrix ctm = new Matrix();
			mCamera.save();
			mCamera.translate(x, t, 0);
			mCamera.rotateZ(degree);
			mCamera.translate(-x, -t, 0);
			mCamera.getMatrix(ctm);
			m.postConcat(ctm);
			canvas.setMatrix(m);
			mCamera.restore();
			break;
		}

			// 翻转
		case 4: {
			float x = child.getLeft() - distance2 + CHILD_WIDTH / 2;
			int y = 0;
			float degree = (distance2 / CHILD_WIDTH * 2) * 90;

			if (degree > 90 || degree < -90) {
				return true;
			}

			canvas.save();
			Matrix ctm = new Matrix();
			mCamera.save();
			mCamera.rotateY(degree);
			mCamera.getMatrix(ctm);
			ctm.preTranslate(-x, -y);
			ctm.postTranslate(x, y);
			canvas.concat(ctm);
			mCamera.restore();
			break;
		}

			// 盒子内
		case 5: {
			float x = child.getLeft() - distance2 + CHILD_WIDTH / 2;
			float y = child.getHeight() / 2;
			float degree;

			if (distance2 > 0) {
				x = child.getLeft();
			} else {
				x = child.getRight();
			}

			int factor = 50;

			degree = -(distance2 / CHILD_WIDTH * 2) * factor;

			if (degree > 90 || degree < -90) {
				return true;
			}

			canvas.save();
			Matrix ctm = new Matrix();
			mCamera.save();
			mCamera.translate(0.0f, 0, 0.0f);
			mCamera.rotateY(degree);
			mCamera.getMatrix(ctm);
			ctm.preTranslate(-x, -y);
			ctm.postTranslate(x, y);
			canvas.concat(ctm);
			mCamera.restore();
			break;
		}

			// 弹跳
		case 6: {
			canvas.save();
			Matrix ctm = new Matrix();
			mCamera.save();
			mCamera.translate(distance2 * 0.0f, Math.abs(distance2) * 0.3f, 0);
			mCamera.getMatrix(ctm);
			canvas.concat(ctm);
			mCamera.restore();
			break;
		}

			// 挤压
		case 7: {
			float x = 0;
			float y = child.getHeight() / 2;

			if (distance2 > 0) {
				x = child.getLeft();
			} else {
				x = child.getRight();
			}

			canvas.save();
			Matrix ctm = new Matrix();
			mCamera.save();
			mCamera.getMatrix(ctm);

			float s = ((CHILD_WIDTH - Math.abs(distance2)) / CHILD_WIDTH);
			ctm.postScale(s, 1, x, y);
			canvas.concat(ctm);
			mCamera.restore();
			break;
		}

			// 波浪
		case 8: {
			float x = 0;
			float y = child.getHeight() / 2;
			if (distance2 > CHILD_WIDTH || distance2 < -CHILD_WIDTH) {
				return true;
			}

			if (distance2 > 0) {
				x = child.getLeft();
			} else {
				x = child.getRight();
			}

			canvas.save();
			Matrix ctm = new Matrix();
			mCamera.save();
			mCamera.getMatrix(ctm);
			float s = ((CHILD_WIDTH - Math.abs(distance2)) / CHILD_WIDTH);
			ctm.postScale(s, s, x, y);
			canvas.concat(ctm);
			mCamera.restore();
			break;
		}

			// 对角线，左上右下
		case 9: {
			if (distance2 > CHILD_WIDTH || distance2 < -CHILD_WIDTH) {
				return true;
			}

			canvas.save();
			Matrix ctm = new Matrix();
			mCamera.save();
			canvas.translate(0, distance2);
			mCamera.getMatrix(ctm);
			canvas.concat(ctm);
			mCamera.restore();
			break;
		}

			// 对角线，左下右上
		case 10: {
			if (distance2 > CHILD_WIDTH || distance2 < -CHILD_WIDTH) {
				return true;
			}

			canvas.save();
			Matrix ctm = new Matrix();
			mCamera.save();
			canvas.translate(0, -distance2);
			mCamera.getMatrix(ctm);
			canvas.concat(ctm);
			mCamera.restore();
			break;
		}

			// 翻滚
		case 11: {
			float x = child.getLeft() + distance2;
			int y = child.getHeight() - 70;
			float degree = -(distance2 / CHILD_WIDTH * 2) * 30;
			canvas.save();

			Matrix ctm = new Matrix();
			mCamera.save();
			mCamera.rotateZ(degree);
			mCamera.getMatrix(ctm);
			ctm.preTranslate(-x, -y);
			ctm.postTranslate(x, y);
			canvas.concat(ctm);
			mCamera.restore();
			break;
		}

		default:
			restore = false;
			break;
		}
		boolean res = super.drawChild(canvas, child, drawingTime);
		if (restore) {
			canvas.restore();
		}
		return res;
	}

	// 贺辉2011年11月9日10:03:44注释，暂时不用
	// public void myLayout(final int mScrollX) {
	// switch (mAninmationType) {
	// case 14:{
	//
	// // if (deltX < 0) {
	// // this.setBackgroundColor(Color.RED);
	// // } else {
	// // this.setBackgroundColor(Color.GRAY);
	// // }
	// int count = this.getChildCount();
	// int width = 320;
	// //保证的滑动的时候图标不动
	// for (int i = 0; i < count; i++) {
	// View v = this.getChildAt(i);
	// int deltX = (mScrollX - v.getLeft());
	// int left = i * width + deltX;
	// int top = 0;
	// // v.layout(left, top, left + width, top + v.getHeight());
	// }
	// break;
	//
	// }
	// default:
	// break;
	// }
	//
	// }

	@Override
	protected void onLayout(final boolean changed, final int left,
			final int top, final int right, final int bottom) {
		LogUtils.d(TAG, "onLayout");

		int childLeft = 0;

		final int count = getChildCount();

		for (int i = 0; i < count; i++) {
			final View child = getChildAt(i);

			if (child.getVisibility() != View.GONE) {
				final int childWidth = child.getMeasuredWidth();
				child.layout(childLeft, 0, childLeft + childWidth,
						child.getMeasuredHeight());
				childLeft += childWidth;
			}
		}

		initPageIndicator();
	}

	@Override
	protected void onMeasure(final int widthMeasureSpec,
			final int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);

		LogUtils.d(TAG, "onMeasure");

		final int width = MeasureSpec.getSize(widthMeasureSpec);
		final int widthMode = MeasureSpec.getMode(widthMeasureSpec);

		if (widthMode != MeasureSpec.EXACTLY) {
			throw new IllegalStateException(
					"Workspace can only be used in EXACTLY mode.");
		}

		final int heightMode = MeasureSpec.getMode(heightMeasureSpec);

		if (heightMode != MeasureSpec.EXACTLY) {
			throw new IllegalStateException(
					"Workspace can only be used in EXACTLY mode.");
		}

		// The children are given the same width and height as the workspace
		final int count = getChildCount();

		for (int i = 0; i < count; i++) {
			getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
		}

		if (mFirstLayout) {
			scrollTo(mCurrentScreen * width, 0);
			updateWallpaperOffset(width * (getChildCount() - 1));
			mFirstLayout = false;
		}
	}

	@Override
	protected boolean onRequestFocusInDescendants(final int direction,
			final Rect previouslyFocusedRect) {
		final Folder openFolder = getOpenFolder();

		if (openFolder != null) {
			return openFolder.requestFocus(direction, previouslyFocusedRect);
		} else {
			int focusableScreen;

			if (mNextScreen != INVALID_SCREEN) {
				focusableScreen = mNextScreen;
			} else {
				focusableScreen = mCurrentScreen;
			}

			getChildAt(focusableScreen).requestFocus(direction,
					previouslyFocusedRect);
		}

		return false;
	}

	@Override
	protected void onRestoreInstanceState(final Parcelable state) {
		SavedState savedState = (SavedState) state;
		super.onRestoreInstanceState(savedState.getSuperState());

		if (savedState.currentScreen != -1) {
			mCurrentScreen = savedState.currentScreen;
			Launcher.setScreen(mCurrentScreen);
		}
	}

	@Override
	protected Parcelable onSaveInstanceState() {
		final SavedState state = new SavedState(super.onSaveInstanceState());
		state.currentScreen = mCurrentScreen;

		return state;
	}

	void addApplicationShortcut(final ShortcutInfo info,
			final CellLayout.CellInfo cellInfo, final boolean insertAtFirst) {
		final CellLayout layout = (CellLayout) getChildAt(cellInfo.screen);
		final int[] result = new int[2];

		layout.cellToPoint(cellInfo.cellX, cellInfo.cellY, result);
		onDropExternal(result[0], result[1], info, layout, insertAtFirst);
	}

	/**
	 * Adds the specified child in the current screen. The position and
	 * dimension of the child are defined by x, y, spanX and spanY.
	 * 
	 * @param child
	 *            The child to add in one of the workspace's screens.
	 * @param x
	 *            The X position of the child in the screen's grid.
	 * @param y
	 *            The Y position of the child in the screen's grid.
	 * @param spanX
	 *            The number of cells spanned horizontally by the child.
	 * @param spanY
	 *            The number of cells spanned vertically by the child.
	 */
	void addInCurrentScreen(final View child, final int x, final int y,
			final int spanX, final int spanY) {
		addInScreen(child, mCurrentScreen, x, y, spanX, spanY, false);
	}

	/**
	 * Adds the specified child in the current screen. The position and
	 * dimension of the child are defined by x, y, spanX and spanY.
	 * 
	 * @param child
	 *            The child to add in one of the workspace's screens.
	 * @param x
	 *            The X position of the child in the screen's grid.
	 * @param y
	 *            The Y position of the child in the screen's grid.
	 * @param spanX
	 *            The number of cells spanned horizontally by the child.
	 * @param spanY
	 *            The number of cells spanned vertically by the child.
	 * @param insert
	 *            When true, the child is inserted at the beginning of the
	 *            children list.
	 */
	void addInCurrentScreen(final View child, final int x, final int y,
			final int spanX, final int spanY, final boolean insert) {
		addInScreen(child, mCurrentScreen, x, y, spanX, spanY, insert);
	}

	/**
	 * Adds the specified child in the specified screen. The position and
	 * dimension of the child are defined by x, y, spanX and spanY.
	 * 
	 * @param child
	 *            The child to add in one of the workspace's screens.
	 * @param screen
	 *            The screen in which to add the child.
	 * @param x
	 *            The X position of the child in the screen's grid.
	 * @param y
	 *            The Y position of the child in the screen's grid.
	 * @param spanX
	 *            The number of cells spanned horizontally by the child.
	 * @param spanY
	 *            The number of cells spanned vertically by the child.
	 */
	void addInScreen(final View child, final int screen, final int x,
			final int y, final int spanX, final int spanY) {
		addInScreen(child, screen, x, y, spanX, spanY, false);
	}

	/**
	 * Adds the specified child in the specified screen. The position and
	 * dimension of the child are defined by x, y, spanX and spanY.
	 * 
	 * @param child
	 *            The child to add in one of the workspace's screens.
	 * @param screen
	 *            The screen in which to add the child.
	 * @param x
	 *            The X position of the child in the screen's grid.
	 * @param y
	 *            The Y position of the child in the screen's grid.
	 * @param spanX
	 *            The number of cells spanned horizontally by the child.
	 * @param spanY
	 *            The number of cells spanned vertically by the child.
	 * @param insert
	 *            When true, the child is inserted at the beginning of the
	 *            children list.
	 * 
	 * @throws IllegalStateException
	 */
	void addInScreen(final View child, final int screen, final int x,
			final int y, final int spanX, final int spanY, final boolean insert) {
		if (screen < 0 || screen >= getChildCount()) {
			throw new IllegalStateException("The screen must be >= 0 and < "
					+ getChildCount());
		}

		clearVacantCache();

		final CellLayout group = (CellLayout) getChildAt(screen);
		CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child
				.getLayoutParams();

		if (lp == null) {
			lp = new CellLayout.LayoutParams(x, y, spanX, spanY);
		} else {
			lp.cellX = x;
			lp.cellY = y;
			lp.cellHSpan = spanX;
			lp.cellVSpan = spanY;
		}

		group.addView(child, insert ? 0 : -1, lp);

		if (!(child instanceof Folder)) {
			child.setOnLongClickListener(mLongClickListener);
		}
	}

	void addWidget(final View view, final Widget widget, final boolean insert) {
		addInScreen(view, widget.screen, widget.cellX, widget.cellY,
				widget.spanX, widget.spanY, insert);
	}

	void clearChildrenCache() {
		final int count = getChildCount();

		for (int i = 0; i < count; i++) {
			final CellLayout layout = (CellLayout) getChildAt(i);
			layout.setChildrenDrawnWithCacheEnabled(false);
		}
	}

	void enableChildrenCache() {
		final int count = getChildCount();

		for (int i = 0; i < count; i++) {
			final CellLayout layout = (CellLayout) getChildAt(i);
			layout.setChildrenDrawnWithCacheEnabled(true);
			layout.setChildrenDrawingCacheEnabled(true);
		}
	}

	CellLayout.CellInfo findAllVacantCells(final boolean[] occupied) {
		CellLayout group = (CellLayout) getChildAt(mCurrentScreen);

		if (group != null) {
			return group.findAllVacantCells(occupied, null);
		}

		return null;
	}

	/**
	 * Returns the index of the currently displayed screen.
	 * 
	 * @return The index of the currently displayed screen.
	 */
	int getCurrentScreen() {
		return mCurrentScreen;
	}

	/**
	 * DOCUMENT ME!
	 * 
	 * @return The open folder on the current screen, or null if there is none
	 */
	Folder getOpenFolder() {
		// Log.e(TAG,""+mCurrentScreen);
		CellLayout currentScreen = (CellLayout) getChildAt(mCurrentScreen);

		if (currentScreen == null) {
			return null;
		}

		int count = currentScreen.getChildCount();

		for (int i = 0; i < count; i++) {
			View child = currentScreen.getChildAt(i);
			CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child
					.getLayoutParams();

			if (lp.cellHSpan == 4 && lp.cellVSpan == 4
					&& child instanceof Folder) {
				return (Folder) child;
			}
		}

		return null;
	}

	ArrayList<Folder> getOpenFolders() {
		final int screens = getChildCount();
		ArrayList<Folder> folders = new ArrayList<Folder>(screens);

		for (int screen = 0; screen < screens; screen++) {
			CellLayout currentScreen = (CellLayout) getChildAt(screen);
			int count = currentScreen.getChildCount();

			for (int i = 0; i < count; i++) {
				View child = currentScreen.getChildAt(i);
				CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child
						.getLayoutParams();

				if (lp.cellHSpan == 4 && lp.cellVSpan == 4
						&& child instanceof Folder) {
					folders.add((Folder) child);

					break;
				}
			}
		}

		return folders;
	}

	boolean isDefaultScreenShowing() {
		return mCurrentScreen == mDefaultScreen;
	}

	void moveToDefaultScreen() {
		snapToScreen(mDefaultScreen);
		getChildAt(mDefaultScreen).requestFocus();
	}

	void removeInScreen(final View view, final int index) {
		if (index < 0 || index >= getChildCount()) {
			StringBuilder info = new StringBuilder()
					.append("The screen must be >= 0 and < ");
			info.append(getChildCount());
			throw new IllegalStateException(info.toString());
		}

		CellLayout localCellLayout = (CellLayout) getChildAt(index);
		ViewGroup localViewGroup = (ViewGroup) view.getParent();

		if (localViewGroup != null) {
			localViewGroup.removeView(view);
		}

		String str2 = "removeInScreen group:" + localCellLayout + "  child:"
				+ view + "  screen:" + index;
		Log.d("Workspace", str2);
	}

	/**
	 * 完整
	 */
	void removeItems(final ArrayList<ApplicationInfo> apps) {
		int i = getChildCount();
		PackageManager localPackageManager = getContext().getPackageManager();
		AppWidgetManager localAppWidgetManager = AppWidgetManager
				.getInstance(getContext());
		HashSet<String> localHashSet = new HashSet<String>();
		int j = apps.size();
		int k = 0;

		while (k < j) {
			String str = ((ApplicationInfo) apps.get(k)).componentName
					.getPackageName();
			localHashSet.add(str);
			k++;
		}

		k = 0;

		while (k < i) {
			CellLayout localCellLayout = (CellLayout) getChildAt(k);
			Workspace2Runnable workspace2Runnable = new Workspace2Runnable(
					this, localCellLayout, localHashSet, localPackageManager,
					localAppWidgetManager);
			post(workspace2Runnable);
			k++;
		}
	}

	void removeShortcutsForPackage(final String packageName) {
		final ArrayList<View> childrenToRemove = new ArrayList<View>();

		// final LauncherModel model = Launcher.getModel();
		final int count = getChildCount();

		for (int i = 0; i < count; i++) {
			final CellLayout layout = (CellLayout) getChildAt(i);
			int childCount = layout.getChildCount();

			childrenToRemove.clear();

			for (int j = 0; j < childCount; j++) {
				final View view = layout.getChildAt(j);
				Object tag = view.getTag();

				if (tag instanceof ShortcutInfo) {
					final ShortcutInfo info = (ShortcutInfo) tag;

					// We need to check for ACTION_MAIN otherwise getComponent()
					// might
					// return null for some shortcuts (for instance, for
					// shortcuts to
					// web pages.)
					final Intent intent = info.intent;
					final ComponentName name = intent.getComponent();

					if (Intent.ACTION_MAIN.equals(intent.getAction())
							&& name != null
							&& packageName.equals(name.getPackageName())) {
						// model.removeDesktopItem(info);
						mLauncher.removeShortcut(info);
						LauncherModel.deleteItemFromDatabase(mLauncher, info);
						childrenToRemove.add(view);
					}
				} else if (tag instanceof UserFolderInfo) {
					final UserFolderInfo info = (UserFolderInfo) tag;
					final ArrayList<ShortcutInfo> contents = info.contents;
					final ArrayList<ShortcutInfo> toRemove = new ArrayList<ShortcutInfo>(
							1);
					boolean removedFromFolder = false;

					for (ShortcutInfo appInfo : contents) {
						final Intent intent = appInfo.intent;
						final ComponentName name = intent.getComponent();

						if (Intent.ACTION_MAIN.equals(intent.getAction())
								&& name != null
								&& packageName.equals(name.getPackageName())) {
							toRemove.add(appInfo);
							LauncherModel.deleteItemFromDatabase(mLauncher,
									appInfo);
							removedFromFolder = true;
						}

					}

					contents.removeAll(toRemove);

					if (removedFromFolder) {
						final Folder folder = getOpenFolder();

						if (folder != null) {
							folder.notifyDataSetChanged();
						}
					}
				}
			}

			childCount = childrenToRemove.size();

			for (int j = 0; j < childCount; j++) {
				layout.removeViewInLayout(childrenToRemove.get(j));
			}

			if (childCount > 0) {
				layout.requestLayout();
				layout.invalidate();
			}
		}
	}

	/**
	 * 完整
	 */
	void resume(final int index) {
		// Log.e(TAG,"resume index "+index);
		int j = getWidth();

		if ((j != 0) && (index >= 0)) {
			Scroller localScroller = this.mScroller;

			if ((localScroller != null) && (!localScroller.isFinished())) {
				localScroller.abortAnimation();
			}

			int k = index * j;
			scrollTo(k, 0);
		}
	}

	void setAtuoScrollScreen(final int index) {
		this.mStartScreen = this.mCurrentScreen;
		this.mEndScreen = index;
		this.mScrollDirection = this.mEndScreen - this.mStartScreen;
		this.mIsAutoScrolling = true;
		postDelayed(this.mAutoScrollRunnable, SCROLL_RESTART_DURATION);
	}

	/**
	 * Sets the current screen.
	 * 
	 * @param currentScreen
	 */
	void setCurrentScreen(final int currentScreen) {
		clearVacantCache();
		// Log.e(TAG,"setCurrentScreen "+currentScreen);
		mCurrentScreen = Math.max(0,
				Math.min(currentScreen, getChildCount() - 1));
		scrollTo(mCurrentScreen * getWidth(), 0);
		invalidate();
	}

	void setLauncher(final Launcher launcher) {
		mLauncher = launcher;
	}

	void setShowIndicator() {
		this.mOpenFlag = true;
	}

	void snapToScreen(final int whichScreen2) {
		// Log.e(TAG, "snapToScreen "+ whichScreen2);
		if (!mScroller.isFinished()) {
			return;
		}

		clearVacantCache();
		enableChildrenCache();

		int whichScreen = Math.max(0,
				Math.min(whichScreen2, getChildCount() - 1));

		boolean changingScreens = whichScreen != mCurrentScreen;

		mNextScreen = whichScreen;

		View focusedChild = getFocusedChild();

		if (focusedChild != null && changingScreens
				&& focusedChild == getChildAt(mCurrentScreen)) {
			focusedChild.clearFocus();
		}

		final int newX = whichScreen * getWidth();
		final int delta = newX - mScrollX;
		mScroller.startScroll(mScrollX, 0, delta, 0, Math.abs(delta) * 5);
		invalidate();
	}

	void startDrag(final CellLayout.CellInfo cellInfo) {
		LogUtils.d(TAG, "startDrag");

		View child = cellInfo.cell;

		// Make sure the drag was started by a long press as opposed to a long
		// click.
		// Note that Search takes focus when clicked rather than entering touch
		// mode
		if (!child.isInTouchMode() && !(child instanceof Search)) {
			return;
		}

		mDragInfo = cellInfo;
		mDragInfo.screen = mCurrentScreen;

		CellLayout current = ((CellLayout) getChildAt(mCurrentScreen));

		current.onDragChild(child);
		mDragger.startDrag(child, this, child.getTag(),
				DragController.DRAG_ACTION_MOVE);
		invalidate();
	}

	void stopAutoScrollRunnable() {
		removeCallbacks(this.mAutoScrollRunnable);
		this.mIsAutoScrolling = false;
	}

	/**
	 * 完整
	 */
	void updateShortcuts(final ArrayList<ApplicationInfo> apps) {
		final int count = getChildCount();

		for (int i = 0; i < count; i++) {
			final CellLayout layout = (CellLayout) getChildAt(i);
			int childCount = layout.getChildCount();

			for (int j = 0; j < childCount; j++) {
				final View view = layout.getChildAt(j);
				Object tag = view.getTag();

				if (tag instanceof ShortcutInfo) {
					ShortcutInfo info = (ShortcutInfo) tag;

					// We need to check for ACTION_MAIN otherwise getComponent()
					// might
					// return null for some shortcuts (for instance, for
					// shortcuts to
					// web pages.)
					final Intent intent = info.intent;
					final ComponentName name = intent.getComponent();

					if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
							&& Intent.ACTION_MAIN.equals(intent.getAction())
							&& name != null) {

						for (ApplicationInfo app : apps) {
							if (mIconCache == null
									&& this.mContext.getApplicationContext() instanceof LauncherApplication) {
								this.mIconCache = ((LauncherApplication) this.mContext
										.getApplicationContext())
										.getIconCache();
							}

							if (mIconCache != null
									&& app.componentName.equals(name)) {
								info.setIcon(mIconCache.getIcon(info.intent));
								((TextView) view)
										.setCompoundDrawablesWithIntrinsicBounds(
												null,
												new FastBitmapDrawable(info
														.getIcon(mIconCache)),
												null, null);
							}
						}
					}
				}
			}
		}
	}

	void updateShortcutsForPackage(final String packageName) {
		int i = getChildCount();
		int j = 0;

		while (j < i) {
			CellLayout localCellLayout = (CellLayout) getChildAt(j);
			int k = localCellLayout.getChildCount();
			int m = 0;

			while (m < k) {
				View localView = localCellLayout.getChildAt(m);
				Object localObject = localView.getTag();

				if ((localObject instanceof ShortcutInfo)) {
					ShortcutInfo localShortcutInfo = (ShortcutInfo) localObject;
					Intent localIntent1 = localShortcutInfo.intent;
					ComponentName localComponentName = localIntent1
							.getComponent();

					if (localShortcutInfo.itemType == 0
							&& (Intent.ACTION_MAIN.equals(localIntent1
									.getAction()))
							&& (localComponentName != null)) {
						String str2 = localComponentName.getPackageName();

						if (packageName.equals(str2)) {
							Intent localIntent2 = localShortcutInfo.intent;
							Bitmap localBitmap1 = this.mIconCache
									.getIcon(localIntent2);
							localShortcutInfo.setIcon(localBitmap1);

							TextView localTextView = (TextView) localView;
							Bitmap localBitmap2 = localShortcutInfo
									.getIcon(this.mIconCache);
							FastBitmapDrawable localFastBitmapDrawable = new FastBitmapDrawable(
									localBitmap2);
							localTextView
									.setCompoundDrawablesWithIntrinsicBounds(
											null, localFastBitmapDrawable,
											null, null);
						}
					}
				}

				m++;
			}

			j++;
		}
	}

	void updateWallpaperOffset() {
		updateWallpaperOffset(getChildAt(getChildCount() - 1).getRight()
				- (mRight - mLeft));
	}

	private void clearVacantCache() {
		if (mVacantCache != null) {
			mVacantCache.clearVacantCells();
			mVacantCache = null;
		}
	}

	private void drawPageIndicator(final Canvas canvas) {
		LogUtils.w(PageIndicator.TAG, "Workspace-drawPageIndicator-start");

		// if(true)
		// return;
		// Log.e(TAG,"drawPageIndicator");
		int i = getWhichScreen();

		// Log.e(TAG,"getWhichScreen  "+i);
		PageIndicator localPageIndicator = this.mPageIndicator;

		if (localPageIndicator == null) {
			return;
		}

		boolean bool = this.mUseLargeDrawablesOnlyForPageIndicator;
		localPageIndicator.setCurrentPage(i, bool);

		int j = this.mPageIndicatorLeft;
		int k = this.mScrollX;
		int m = j + k;
		int n = this.mPageIndicatorTop;

		// Paint p= new Paint();
		// p.setColor(Color.BLACK);
		// canvas.drawText("1234567",m, 20, p);
		localPageIndicator.setOffset(m, n);

		if (!localPageIndicator.draw(canvas)) {
			postInvalidate();
		}

		LogUtils.w(PageIndicator.TAG, "Workspace-drawPageIndicator-end");
	}

	/**
	 * Calculate the nearest cell where the given object would be dropped.
	 */
	private int[] estimateDropCell(final int pixelX, final int pixelY,
			final int spanX, final int spanY, final View ignoreView,
			final CellLayout layout, final int[] recycle) {
		// Create vacant cell cache if none exists
		if (mVacantCache == null) {
			mVacantCache = layout.findAllVacantCells(null, ignoreView);
		}

		// Find the best target drop location
		return layout.findNearestVacantArea(pixelX, pixelY, spanX, spanY,
				mVacantCache, recycle);
	}

	/**
	 * Find a search widget on the given screen
	 */
	private Search findSearchWidget(final CellLayout screen) {
		final int count = screen.getChildCount();

		for (int i = 0; i < count; i++) {
			View v = screen.getChildAt(i);

			if (v instanceof Search) {
				return (Search) v;
			}
		}

		return null;
	}

	/**
	 * Return the current {@link CellLayout}, correctly picking the destination
	 * screen while a scroll is in progress.
	 */
	private CellLayout getCurrentDropLayout() {
		int index = mScroller.isFinished() ? mCurrentScreen : mNextScreen;

		return (CellLayout) getChildAt(index);
	}

	private int getWhichScreen() {
		int i = getWidth();
		int j = getChildCount();
		int k = this.mScrollX;
		int m = j - 1;
		int n = getChildAt(m).getRight() - k;
		int i1 = getWidth();
		int i2 = n - i1;
		int i3;

		if (k < 0) {
			return 0;
		}

		if (i2 <= 0) {
			i3 = j - 1;
		}

		i3 = (i / 2 + k) / i;

		return i3;
	}

	private void initPageIndicator() {
		int i = 0;

		if (this.mPageIndicator == null) {
			this.mPageIndicator = new PageIndicator();
		}

		int j = getChildCount();
		int k = this.mPageIndicatorLarge.getIntrinsicWidth();
		this.mPageIndicator.setPageDrawable(mPageIndicatorLarge);
		mPageIndicator.setPageCount(j);
		mPageIndicator.setGap(this.mPageIndicatorGap);

		int n = this.mTextSize;
		mPageIndicator.setTextSize(n);

		if (this.mEnablePageIndicatorShowHide) {
			mPageIndicator.enableShowHide(true);

			int i1 = k * j;
			int i2 = this.mPageIndicatorGap;

			if (j > 0) {
				i = j - 1;
			}

			int i3 = i2 * i;
			int i4 = i1 + i3;
			int i5 = (getWidth() - i4) / 2;
			this.mPageIndicatorLeft = i5;
		} else {
			mPageIndicator.enableShowHide(false);
		}
	}

	/**
	 * Initializes various states for this workspace.
	 */
	private void initWorkspace() {
		// this.setBackgroundColor(Color.RED);
		mScroller = new Scroller(getContext());
		mCurrentScreen = mDefaultScreen;
		Launcher.setScreen(mCurrentScreen);

		Context app = getContext().getApplicationContext();

		if (app instanceof LauncherApplication) {
			this.mIconCache = ((LauncherApplication) app).getIconCache();
		}

		final ViewConfiguration configuration = ViewConfiguration
				.get(getContext());
		mTouchSlop = configuration.getScaledTouchSlop();
		// mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();

		// Wysie: Use MultiTouchController only for multitouch events
		multiTouchController = new MultiTouchController<Object>(this, false);

		Resources localResources = getResources();
		this.mPageIndicatorSmall = localResources
				.getDrawable(R.drawable.homescreen_menu_page_focus_small);
		this.mPageIndicatorMiddle = localResources
				.getDrawable(R.drawable.homescreen_menu_page_focus_middle);
		this.mPageIndicatorLarge = localResources
				.getDrawable(R.drawable.homescreen_menu_page_focus_large);
		this.mPageIndicatorTop = localResources
				.getDimensionPixelSize(R.dimen.workspace_pageindicator_top);
		this.mPageIndicatorGap = localResources
				.getDimensionPixelSize(R.dimen.pageindicator_gap);

		// this.mChildTopOffset =
		// localResources.getDimensionPixelSize(R.dimen.cell_top);

		Drawable localDrawable4 = this.mPageIndicatorSmall;
		int i3 = this.mPageIndicatorSmall.getIntrinsicWidth();
		int i4 = this.mPageIndicatorSmall.getIntrinsicHeight();
		localDrawable4.setBounds(0, 0, i3, i4);

		Drawable localDrawable5 = this.mPageIndicatorMiddle;
		int i5 = this.mPageIndicatorMiddle.getIntrinsicWidth();
		int i6 = this.mPageIndicatorMiddle.getIntrinsicHeight();
		localDrawable5.setBounds(0, 0, i5, i6);

		Drawable localDrawable6 = this.mPageIndicatorLarge;
		int i7 = this.mPageIndicatorLarge.getIntrinsicWidth();
		int i8 = this.mPageIndicatorLarge.getIntrinsicHeight();
		localDrawable6.setBounds(0, 0, i7, i8);
		this.mTextSize = localResources
				.getDimensionPixelSize(R.dimen.pageindicator_fontsize);
		this.mEnablePageIndicatorShowHide = localResources
				.getBoolean(R.bool.pageindicator_showhide_enable);
		this.mOpenFlag = true;
	}

	private void onDropExternal(final int x, final int y,
			final Object dragInfo, final CellLayout cellLayout) {
		onDropExternal(x, y, dragInfo, cellLayout, false);

		LogUtils.d(TAG, "onDropExternal1");
	}

	private void onDropExternal(final int x, final int y,
			final Object dragInfo, final CellLayout cellLayout,
			final boolean insertAtFirst) {
		LogUtils.d(TAG, "onDropExternal2");

		// Drag from somewhere else
		ItemInfo info = (ItemInfo) dragInfo;

		// Log.e(TAG,"onDropExternal "+info.itemType);
		View view;

		switch (info.itemType) {
		case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
		case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:

			if (info.container == NO_ID && info instanceof ApplicationInfo) {
				// Came from all apps -- make a copy
				info = new ShortcutInfo((ApplicationInfo) info);

				// info = new ApplicationInfo((ApplicationInfo) info);
			}

			view = mLauncher.createShortcut(R.layout.application, cellLayout,
					(ShortcutInfo) info);

			break;

		case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
			view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher,
					(ViewGroup) getChildAt(mCurrentScreen),
					((UserFolderInfo) info));

			break;

		default:
			throw new IllegalStateException("Unknown item type: "
					+ info.itemType);
		}

		cellLayout.addView(view, insertAtFirst ? 0 : -1);
		view.setOnLongClickListener(mLongClickListener);
		mTargetCell = estimateDropCell(x, y, 1, 1, view, cellLayout,
				mTargetCell);
		cellLayout.onDropChild(view, mTargetCell);

		CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view
				.getLayoutParams();

		// final LauncherModel model = Launcher.getModel();
		mLauncher.addShortcut(info);
		// model.addDesktopItem(info);
		LauncherModel.addOrMoveItemInDatabase(mLauncher, info,
				LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentScreen,
				lp.cellX, lp.cellY);
	}

	private void snapToDestination() {
		final int screenWidth = getWidth();
		final int whichScreen = (mScrollX + (screenWidth / 2)) / screenWidth;

		snapToScreen(whichScreen);
	}

	private void updateWallpaperOffset(final int scrollRange) {
		mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1),
				0);
		mWallpaperManager.setWallpaperOffsets(getWindowToken(), mScrollX
				/ (float) scrollRange, 0);
	}

	// ~ Inner Classes
	// ----------------------------------------------------------
	public static class SavedState extends BaseSavedState {
		int currentScreen = -1;

		public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
			public SavedState createFromParcel(final Parcel in) {
				return new SavedState(in);
			}

			public SavedState[] newArray(final int size) {
				return new SavedState[size];
			}
		};

		/**
		 * Creates a new SavedState object.
		 */
		SavedState(final Parcelable superState) {
			super(superState);
		}

		/**
		 * Creates a new SavedState object.
		 */
		private SavedState(final Parcel in) {
			super(in);
			currentScreen = in.readInt();
		}

		@Override
		public void writeToParcel(final Parcel out, final int flags) {
			super.writeToParcel(out, flags);
			out.writeInt(currentScreen);
		}
	}

	class Workspace2Runnable implements Runnable {
		AppWidgetManager mAppWidgetManager = null;
		PackageManager mPackageManager = null;
		Workspace mWorkspace = null;
		private CellLayout mCellLayout = null;
		private HashSet mPackageName = null;

		/**
		 * Creates a new Workspace2Runnable object.
		 */
		public Workspace2Runnable(final Workspace localWorkspace,
				final CellLayout localCellLayout, final HashSet localHashSet,
				final PackageManager localPackageManager,
				final AppWidgetManager localAppWidgetManager) {
			mWorkspace = localWorkspace;
			mPackageManager = localPackageManager;
			mCellLayout = localCellLayout;
			mAppWidgetManager = localAppWidgetManager;
			mPackageName = localHashSet;
		}

		public void run() {
			ArrayList<View> localArrayList1 = new ArrayList<View>();
			localArrayList1.clear();

			int i = this.mCellLayout.getChildCount();

			// int j = 0;
			// if (j < i)
			// {
			for (int j = 0; j < i; j++) {
				CellLayout localCellLayout1 = this.mCellLayout;

				// int k = j;
				View localView1 = localCellLayout1.getChildAt(j);
				ItemInfo localObject1 = (ItemInfo) localView1.getTag();
				ItemInfo localObject2;
				ComponentName localComponentName;
				Iterator localIterator;

				if ((localObject1 instanceof ShortcutInfo)) {
					localObject2 = (ShortcutInfo) localObject1;

					Intent localIntent1 = ((ShortcutInfo) localObject2).intent;
					localComponentName = localIntent1.getComponent();

					String str1 = localIntent1.getAction();

					if (("android.intent.action.MAIN".equals(str1))
							&& (localComponentName != null)) {
						localIterator = this.mPackageName.iterator();

						while (localIterator.hasNext()) {
							String str2 = (String) localIterator.next();
							String str3 = localComponentName.getPackageName();
							String str4 = str2;
							String str5 = str3;

							if (!str4.equals(str5)) {
								continue;
							}

							Launcher localLauncher1 = mLauncher;
							ItemInfo localObject3 = localObject2;
							LauncherModel.deleteItemFromDatabase(
									localLauncher1, localObject3);

							ArrayList localArrayList2 = localArrayList1;
							View localView2 = localView1;
							boolean bool1 = localArrayList2.add(localView2);
						}
					}
				} else {
					if (!(localObject1 instanceof UserFolderInfo)) {
						if ((localObject1 instanceof LiveFolderInfo)) {
							localObject2 = (LiveFolderInfo) localObject1;

							Uri localUri = ((LiveFolderInfo) localObject2).uri;
							PackageManager localPackageManager = this.mPackageManager;
							String str11 = localUri.getAuthority();
							ProviderInfo localProviderInfo = localPackageManager
									.resolveContentProvider(str11, 0);

							if (localProviderInfo == null) {
								continue;
							}

							localIterator = this.mPackageName.iterator();

							while (localIterator.hasNext()) {
								String str12 = (String) localIterator.next();
								String str13 = localProviderInfo.packageName;
								String str14 = str12;
								String str15 = str13;

								if (!str14.equals(str15)) {
									continue;
								}

								// Launcher localLauncher3 =
								// Workspace.access$100(this.this$0);mLauncher
								Launcher localLauncher3 = mLauncher;
								ItemInfo localObject4 = localObject2;
								LauncherModel.deleteItemFromDatabase(
										localLauncher3, localObject4);

								ArrayList localArrayList9 = localArrayList1;
								View localView3 = localView1;
								boolean bool4 = localArrayList9.add(localView3);
							}

							continue;
						}

						if ((localObject1 instanceof LauncherAppWidgetInfo)) {
							localObject2 = (LauncherAppWidgetInfo) localObject1;

							AppWidgetManager localAppWidgetManager = this.mAppWidgetManager;
							int i3 = ((LauncherAppWidgetInfo) localObject2).appWidgetId;
							AppWidgetProviderInfo localAppWidgetProviderInfo = localAppWidgetManager
									.getAppWidgetInfo(i3);

							if (localAppWidgetProviderInfo == null) {
								continue;
							}

							localIterator = this.mPackageName.iterator();

							while (localIterator.hasNext()) {
								String str16 = (String) localIterator.next();
								String str17 = localAppWidgetProviderInfo.provider
										.getPackageName();
								String str18 = str16;
								String str19 = str17;

								if (!str18.equals(str19)) {
									continue;
								}

								Launcher localLauncher4 = mLauncher;
								ItemInfo localObject5 = localObject2;
								LauncherModel.deleteItemFromDatabase(
										localLauncher4, localObject5);

								ArrayList localArrayList10 = localArrayList1;
								View localView4 = localView1;
								boolean bool5 = localArrayList10
										.add(localView4);
							}
						}
					} else {
						ArrayList localArrayList3 = ((UserFolderInfo) localObject1).contents;

						// ArrayList localArrayList4 = new ArrayList(1);
						ArrayList localArrayList5 = new ArrayList(1);

						// int m = 1;
						// localArrayList5.<init>(m);
						int n = localArrayList3.size();
						int i1 = 0;
						int i2 = 0;

						while (i2 < n) {
							ShortcutInfo localShortcutInfo1 = (ShortcutInfo) localArrayList3
									.get(i2);
							Intent localIntent2 = localShortcutInfo1.intent;
							localComponentName = localIntent2.getComponent();

							String str6 = localIntent2.getAction();

							if (("android.intent.action.MAIN".equals(str6))
									&& (localComponentName != null)) {
								localIterator = this.mPackageName.iterator();

								while (localIterator.hasNext()) {
									String str7 = (String) localIterator.next();
									String str8 = localComponentName
											.getPackageName();
									String str9 = str7;
									String str10 = str8;

									if (!str9.equals(str10)) {
										continue;
									}

									ArrayList localArrayList6 = localArrayList5;
									ShortcutInfo localShortcutInfo2 = localShortcutInfo1;
									boolean bool2 = localArrayList6
											.add(localShortcutInfo2);
									Launcher localLauncher2 = mLauncher;
									ShortcutInfo localShortcutInfo3 = localShortcutInfo1;
									LauncherModel.deleteItemFromDatabase(
											localLauncher2, localShortcutInfo3);
									i1 = 1;
								}
							}

							i2 += 1;
						}

						ArrayList localArrayList7 = localArrayList3;
						ArrayList localArrayList8 = localArrayList5;
						boolean bool3 = localArrayList7
								.removeAll(localArrayList8);

						if (i1 != 0) {
							Folder localFolder = this.mWorkspace
									.getOpenFolder();

							if (localFolder != null) {
								localFolder.notifyDataSetChanged();
							}
						}
					}

					// while (true)
					// {
					// j += 1;
					// break;
					// label459:
					// continue;
					// }

					// if (!(localObject1 instanceof SamsungAppWidgetInfo))
					// continue;
					// localObject2 = (SamsungAppWidgetInfo)localObject1;
					// SamsungWidgetPackageManager
					// localSamsungWidgetPackageManager1 =
					// SamsungWidgetPackageManager.getInstance();
					// localIterator = this.val$packageNames.iterator();
					// while (localIterator.hasNext())
					// {
					// String str20 = (String)localIterator.next();
					// String str21 =
					// ((SamsungAppWidgetInfo)localObject2).packageName;
					// String str22 = str20;
					// String str23 = str21;
					// if (!str22.equals(str23))
					// continue;
					// Launcher localLauncher5 =
					// Workspace.access$100(this.this$0);
					// SamsungWidgetPackageManager
					// localSamsungWidgetPackageManager2 =
					// localSamsungWidgetPackageManager1;
					// Launcher localLauncher6 = localLauncher5;
					// Object localObject6 = localObject2;
					// localSamsungWidgetPackageManager2.destroyWidget(localLauncher6,
					// localObject6);
					// Launcher localLauncher7 =
					// Workspace.access$100(this.this$0);
					// Object localObject7 = localObject2;
					// LauncherModel.deleteItemFromDatabase(localLauncher7,
					// localObject7);
					// ArrayList localArrayList11 = localArrayList1;
					// View localView5 = localView1;
					// boolean bool6 = localArrayList11.add(localView5);
					// }
				}
			}

			i = localArrayList1.size();

			int j = 0;

			while (j < i) {
				this.mCellLayout.removeViewInLayout(localArrayList1.get(j));
				j++;
			}

			if (i > 0) {
				this.mCellLayout.requestLayout();
				this.mCellLayout.invalidate();
			}
		}
	}

	/**
	 * Wysie: Multitouch methods/events
	 */
	@Override
	public Object getDraggableObjectAtPoint(PointInfo touchPoint) {
		return this;
	}

	@Override
	public void getPositionAndScale(Object obj,
			PositionAndScale objPosAndScaleOut) {
		objPosAndScaleOut.set(0.0f, 0.0f, true, 1.0f, false, 0.0f, 0.0f, false,
				0.0f);
	}

	@Override
	public boolean setPositionAndScale(Object obj,
			PositionAndScale newObjPosAndScale, PointInfo touchPoint) {
		float newRelativeScale = newObjPosAndScale.getScale();
		int targetZoom = (int) Math.round(Math.log(newRelativeScale)
				* ZOOM_LOG_BASE_INV);
		// Only works for pinch in
		if (targetZoom < 0 && mStatus == SENSE_CLOSED) { // Change to > 0 for
															// pinch out, != 0
															// for both pinch in
															// and out.
			// mLauncher.showPreviews(mLauncher.getDrawerHandle(), 0,
			// getChildCount());
			invalidate();
			return true;
		}
		return false;
	}

	@Override
	public void selectObject(Object obj, PointInfo touchPoint) {
		if (mStatus != SENSE_OPEN) {
			mAllowLongPress = false;
		} else {
			mAllowLongPress = true;
		}
	}
}
